package com.rbac.admin.service.system.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.rbac.admin.common.util.PasswordUtil;
import com.rbac.admin.dto.system.UserDTO;
import com.rbac.admin.entity.system.SystemUser;
import com.rbac.admin.entity.system.SystemRole;
import com.rbac.admin.entity.system.SystemUserRole;
import com.rbac.admin.mapper.system.UserMapper;
import com.rbac.admin.mapper.system.UserRoleMapper;
import com.rbac.admin.service.system.RoleService;
import com.rbac.admin.service.system.UserService;
import com.rbac.admin.service.system.UserDeptService;
import com.rbac.admin.utils.FileUtils;
import com.rbac.admin.vo.system.DeptVO;
import com.rbac.admin.vo.system.RoleVO;
import com.rbac.admin.vo.system.UserVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 用户服务实现类
 *
 * @author rbac-admin
 * @since 2024-07-18
 */
@Slf4j
@Service
public class UserServiceImpl extends ServiceImpl<UserMapper, SystemUser> implements UserService {

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private RoleService roleService;

    @Autowired
    private UserDeptService userDeptService;

    @Override
    public SystemUser getUserByUsername(String username) {
        return userMapper.selectByUsername(username);
    }

    @Override
    public IPage<UserVO> getUserPage(Page<UserVO> page, SystemUser user) {
        // 调用基础查询获取分页数据
        IPage<UserVO> pageResult = userMapper.selectUserPage(page, user);
        
        // 如果有数据，为每个用户加载角色信息和部门信息
        if (pageResult != null && pageResult.getRecords() != null && !pageResult.getRecords().isEmpty()) {
            for (UserVO userVO : pageResult.getRecords()) {
                // 获取用户角色
                List<SystemRole> roles = roleService.getRolesByUserId(userVO.getId());
                if (roles != null && !roles.isEmpty()) {
                    List<RoleVO> roleVOs = roles.stream().map(role -> {
                        RoleVO roleVO = new RoleVO();
                        roleVO.setId(String.valueOf(role.getId()));
                        roleVO.setRoleName(role.getRoleName());
                        roleVO.setRoleCode(role.getRoleCode());
                        roleVO.setStatus(role.getStatus());
                        return roleVO;
                    }).collect(Collectors.toList());
                    userVO.setRoles(roleVOs);
                } else {
                    // 设置空角色列表，避免前端出现 null 值
                    userVO.setRoles(new ArrayList<>());
                }
                
                // 获取用户多部门信息
                List<DeptVO> depts = userDeptService.getDeptsByUserId(userVO.getId());
                userVO.setDepts(depts != null ? depts : new ArrayList<>());
            }
        }
        
        return pageResult;
    }

    @Override
    public UserVO getUserById(String userId) {
        // 获取基础用户信息
        UserVO userVO = userMapper.selectUserById(userId);
        if (userVO == null) {
            return null;
        }
        
        // 获取用户角色
        List<SystemRole> roles = roleService.getRolesByUserId(userId);
        if (roles != null && !roles.isEmpty()) {
            List<RoleVO> roleVOs = roles.stream().map(role -> {
                RoleVO roleVO = new RoleVO();
                roleVO.setId(String.valueOf(role.getId()));
                roleVO.setRoleName(role.getRoleName());
                roleVO.setRoleCode(role.getRoleCode());
                roleVO.setStatus(role.getStatus());
                return roleVO;
            }).collect(Collectors.toList());
            userVO.setRoles(roleVOs);
        } else {
            userVO.setRoles(new ArrayList<>());
        }
        
        // 获取用户多部门信息
        List<DeptVO> depts = userDeptService.getDeptsByUserId(userId);
        userVO.setDepts(depts != null ? depts : new ArrayList<>());
        
        return userVO;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVO createUser(UserDTO userDTO) {
        try {
            // 处理Base64头像数据
            processUserAvatar(userDTO);
            
            // 创建用户实体
            SystemUser user = new SystemUser();
            BeanUtils.copyProperties(userDTO, user);
            
            // 设置默认值 - MyBatis-Plus会自动处理ID生成
            user.setCreateTime(LocalDateTime.now());
            user.setUpdateTime(LocalDateTime.now());
            user.setDeleteFlag(0);
            
            // 加密密码
            if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
                user.setPassword(PasswordUtil.encode(userDTO.getPassword()));
            } else {
                // 设置默认密码
                user.setPassword(PasswordUtil.encode("123456"));
            }
            
            // 保存用户
            boolean saved = this.save(user);
            if (!saved) {
                throw new RuntimeException("创建用户失败");
            }
            
            // 分配角色
            if (userDTO.getRoleIds() != null && !userDTO.getRoleIds().isEmpty()) {
                assignRoles(String.valueOf(user.getId()), userDTO.getRoleIds());
            }
            
            // 保存用户部门关联
            if (userDTO.getDeptIds() != null && !userDTO.getDeptIds().isEmpty()) {
                userDeptService.saveUserDepts(String.valueOf(user.getId()), userDTO.getDeptIds(), userDTO.getMainDeptId());
            }
            
            // 返回用户信息
            return getUserById(String.valueOf(user.getId()));
        } catch (Exception e) {
            throw new RuntimeException("创建用户失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public UserVO updateUser(String userId, UserDTO userDTO) {
        try {
            // 处理Base64头像数据
            processUserAvatar(userDTO);
            
            // 获取现有用户
            SystemUser existUser = this.getById(userId);
            if (existUser == null) {
                throw new RuntimeException("用户不存在");
            }
            
            // 更新用户信息
            BeanUtils.copyProperties(userDTO, existUser, "id", "password", "createTime");
            existUser.setUpdateTime(LocalDateTime.now());
            
            // 如果提供了新密码，则更新密码
            if (userDTO.getPassword() != null && !userDTO.getPassword().isEmpty()) {
                existUser.setPassword(PasswordUtil.encode(userDTO.getPassword()));
            }
            
            // 保存用户
            boolean updated = this.updateById(existUser);
            if (!updated) {
                throw new RuntimeException("更新用户失败");
            }
            
            // 更新角色分配
            if (userDTO.getRoleIds() != null) {
                assignRoles(userId, userDTO.getRoleIds());
            }
            
            // 更新用户部门关联
            if (userDTO.getDeptIds() != null) {
                userDeptService.updateUserDepts(userId, userDTO.getDeptIds(), userDTO.getMainDeptId());
            }
            
            // 返回更新后的用户信息
            return getUserById(userId);
        } catch (Exception e) {
            throw new RuntimeException("更新用户失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean deleteUser(String userId) {
        try {
            // 检查用户是否存在
            SystemUser user = this.getById(userId);
            if (user == null) {
                return false;
            }
            
            // 逻辑删除用户 - MyBatis-Plus的@TableLogic会自动处理
            boolean deleted = this.removeById(userId);
            
            if (deleted) {
                // 删除用户角色关联关系
                clearUserRoles(userId);
            }
            
            return deleted;
        } catch (Exception e) {
            throw new RuntimeException("删除用户失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean batchDeleteUsers(List<String> userIds) {
        try {
            if (userIds == null || userIds.isEmpty()) {
                return false;
            }
            
            // 批量逻辑删除 - MyBatis-Plus的@TableLogic会自动处理
            boolean deleted = this.removeByIds(userIds);
            
            if (deleted) {
                // 批量清除用户角色关联
                for (String userId : userIds) {
                    clearUserRoles(userId);
                }
            }
            
            return deleted;
        } catch (Exception e) {
            throw new RuntimeException("批量删除用户失败：" + e.getMessage(), e);
        }
    }

    @Override
    public boolean resetPassword(String userId, String newPassword) {
        try {
            SystemUser user = this.getById(userId);
            if (user == null) {
                return false;
            }
            
            // 使用默认密码或指定密码
            String password = (newPassword != null && !newPassword.isEmpty()) ? newPassword : "123456";
            user.setPassword(PasswordUtil.encode(password));
            user.setUpdateTime(LocalDateTime.now());
            
            return this.updateById(user);
        } catch (Exception e) {
            throw new RuntimeException("重置密码失败：" + e.getMessage(), e);
        }
    }

    @Override
    public boolean changeStatus(String userId, Integer status) {
        try {
            SystemUser user = this.getById(userId);
            if (user == null) {
                return false;
            }
            
            user.setStatus(status);
            user.setUpdateTime(LocalDateTime.now());
            
            return this.updateById(user);
        } catch (Exception e) {
            throw new RuntimeException("修改用户状态失败：" + e.getMessage(), e);
        }
    }

    @Override
    public List<String> getUserRoleIds(String userId) {
        try {
            return userRoleMapper.selectRoleIdsByUserId(userId);
        } catch (Exception e) {
            throw new RuntimeException("获取用户角色失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean assignRoles(String userId, List<String> roleIds) {
        try {
            // 先清除现有的角色分配
            clearUserRoles(userId);
            
            // 分配新的角色
            if (roleIds != null && !roleIds.isEmpty()) {
                List<SystemUserRole> userRoles = new ArrayList<>();
                int i = 0;
                for (String roleId : roleIds) {
                    SystemUserRole userRole = new SystemUserRole();
                    // 使用更随机的方法生成唯一ID
                    userRole.setId(Math.abs(UUID.randomUUID().hashCode()));
                    userRole.setUserId(userId);
                    userRole.setRoleId(roleId);
                    userRole.setCreateTime(LocalDateTime.now());
                    userRoles.add(userRole);
                }
                
                int insertCount = userRoleMapper.batchInsert(userRoles);
                log.info("用户角色分配成功：userId={}, roleIds={}, insertCount={}", userId, roleIds, insertCount);
                return insertCount > 0;
            }
            
            return true;
        } catch (Exception e) {
            throw new RuntimeException("分配用户角色失败：" + e.getMessage(), e);
        }
    }

    @Override
    public String exportUserData(SystemUser queryUser) {
        try {
            // 查询用户数据
            QueryWrapper<SystemUser> wrapper = new QueryWrapper<>();
            
            if (queryUser.getUsername() != null && !queryUser.getUsername().isEmpty()) {
                wrapper.like("username", queryUser.getUsername());
            }
            if (queryUser.getNickname() != null && !queryUser.getNickname().isEmpty()) {
                wrapper.like("nickname", queryUser.getNickname());
            }
            if (queryUser.getStatus() != null) {
                wrapper.eq("status", queryUser.getStatus());
            }
            
            List<SystemUser> users = this.list(wrapper);
            
            // 这里应该生成Excel文件并返回文件路径
            // 暂时返回一个模拟的文件路径
            String fileName = "users_export_" + System.currentTimeMillis() + ".xlsx";
            String filePath = "/tmp/exports/" + fileName;
            
            // TODO: 实际实现Excel导出逻辑
            log.info("导出用户数据：{} 条记录", users.size());
            
            return filePath;
        } catch (Exception e) {
            throw new RuntimeException("导出用户数据失败：" + e.getMessage(), e);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Map<String, Object> importUserData(MultipartFile file) {
        try {
            Map<String, Object> result = new HashMap<>();
            int successCount = 0;
            int failCount = 0;
            List<String> errors = new ArrayList<>();
            
            // TODO: 实际实现Excel文件解析和用户数据导入逻辑
            log.info("导入用户数据：文件名={}, 大小={}", file.getOriginalFilename(), file.getSize());
            
            result.put("successCount", successCount);
            result.put("failCount", failCount);
            result.put("errors", errors);
            
            return result;
        } catch (Exception e) {
            throw new RuntimeException("导入用户数据失败：" + e.getMessage(), e);
        }
    }

    /**
     * 清除用户角色关联关系
     *
     * @param userId 用户ID
     */
    private void clearUserRoles(String userId) {
        try {
            int deleteCount = userRoleMapper.deleteByUserId(userId);
            log.info("清除用户角色关联成功：userId={}, deleteCount={}", userId, deleteCount);
        } catch (Exception e) {
            log.error("清除用户角色关联失败：userId={}", userId, e);
            throw e; // 重新抛出异常，确保事务回滚
        }
    }

    /**
     * 处理用户头像Base64数据
     * 如果头像是Base64数据，则转换为文件并更新URL
     *
     * @param userDTO 用户数据
     */
    private void processUserAvatar(UserDTO userDTO) {
        try {
            if (userDTO.getAvatar() != null && FileUtils.isBase64Image(userDTO.getAvatar())) {
                // 将Base64图片转换为文件并获取URL
                String avatarUrl = FileUtils.saveBase64ImageIfNeeded("Profile-picture",userDTO.getAvatar());
                userDTO.setAvatar(avatarUrl);
                log.info("处理用户头像成功: {}", avatarUrl);
            }
        } catch (Exception e) {
            log.error("处理用户头像失败: {}", e.getMessage(), e);
            // 不阻止用户创建/更新，仅记录日志
        }
    }
} 